// svgAnimationManager.ts
// 这个模块封装了一系列对 SVG 元素进行动画的函数，
// 通过在 SVG 元素上添加 class 或动态插入 <filter>、<style>，实现各种动画效果。
// 添加类型声明
declare module 'vue' {
  interface HTMLAttributes {
    _hoverScaleListeners?: Record<string, EventListener>;
    _glowFilterId?: string;
    _clickRippleHandler?: EventListener;
    _originalFill?: string; // 添加原始颜色存储
    _colorGroupState?: number; // 分组状态存储
  }
}


const blinkMap = new WeakMap<SVGElement, number>();

/**
 * 闪烁动画（通过切换元素可见性实现）
 * @param el 目标 SVG 元素
 * @param options.interval 闪烁间隔（毫秒），默认 500ms
 */
export function applyBlink(el: SVGElement, { interval = 500 } = {}) {
  removeBlink(el); // 防止重复绑定
  let visible = true;
  const timerId = window.setInterval(() => {
    visible = !visible;
    el.style.visibility = visible ? 'visible' : 'hidden';
  }, interval);
  blinkMap.set(el, timerId);
}

/**
 * 移除闪烁动画
 */
export function removeBlink(el: SVGElement) {
  const timerId = blinkMap.get(el);
  if (timerId !== undefined) {
    clearInterval(timerId);
    blinkMap.delete(el);
  }
  el.style.visibility = 'visible';
}

/**
 * 应用颜色变化动画（支持分组）
 * @param el 目标 SVG 元素或组
 * @param state 状态信息：1表示应用变色，0表示恢复原色
 * @param targetColor 目标颜色（十六进制或颜色名称），可选，默认为绿色
 */

export function applyColorChange(el: SVGElement, state: number, targetColor: string = "#00FF00", type: 'normal' | 'red' = 'normal') {
  if (!(el as any)._originalFill) {
    (el as any)._originalFill = el.style.fill || getComputedStyle(el).fill;
  }

  if (type === 'red') {
    el.dataset.redLock = state === 1 ? 'true' : 'false';
  } else {
    el.dataset.normalLock = state === 1 ? 'true' : 'false';
  }

  // 决定最终颜色优先级：红色优先
  if (el.dataset.redLock === 'true') {
    el.style.transition = 'fill 0.4s ease-in-out';
    el.style.fill = 'red'; // 这里你也可以用参数传入的targetColor
  } else if (el.dataset.normalLock === 'true') {
    el.style.transition = 'fill 0.4s ease-in-out';
    el.style.fill = targetColor;
  } else {
    el.style.transition = 'fill 0.4s ease-in-out';
    el.style.fill = (el as any)._originalFill;
  }
}

/**
 * 移除颜色变化动画并恢复原色（支持分组）
 * @param el 目标 SVG 元素
 */
export function removeColorChange(el: SVGElement) {
  // 如果是组元素，处理所有子元素
  if (el.tagName.toLowerCase() === 'g') {
    Array.from(el.children).forEach(child => {
      if (child instanceof SVGElement) {
        removeColorChange(child);
      }
    });
    return;
  }

  if ((el as any)._originalFill) {
    el.style.transition = '';
    el.style.fill = (el as any)._originalFill;
    delete (el as any)._originalFill;
  } else {
    el.style.transition = '';
    el.style.fill = '';
  }
}

// 动画速度类型
// 'slow' 4s 一圈， 'normal' 2s 一圈， 'fast' 1s 一圈
type Speed = 'slow' | 'normal' | 'fast';
// 抖动方向类型，可指定 x 轴或 y 轴抖动
type Direction = 'x' | 'y';

/**
 * 悬浮缩放动画
 * @param el 目标 SVG 元素
 * @param options.scale 放大比例，默认为 1.1
 */

export function applyHoverScale(el: SVGElement, { scale = 1.1 } = {}) {
  // 清理旧的监听器
  removeHoverScale(el);

  const mouseenter = () => el.style.transform = `scale(${scale})`;
  const mouseleave = () => el.style.transform = 'scale(1)';
  
  el.style.transformBox = 'fill-box';
  el.style.transformOrigin = '50% 50%';
  el.style.transition = 'transform 0.3s';
  
  el.addEventListener('mouseenter', mouseenter);
  el.addEventListener('mouseleave', mouseleave);
  
  // 保存监听器引用以便移除
  el._hoverScaleListeners = { mouseenter, mouseleave };
}
/**
 * 移除悬浮缩放动画
 * @param el 目标 SVG 元素
 */
export function removeHoverScale(el: SVGElement) {
  const listeners = (el as any)._hoverScaleListeners;
  if (listeners) {
    el.removeEventListener('mouseenter', listeners.mouseenter);
    el.removeEventListener('mouseleave', listeners.mouseleave);
    delete (el as any)._hoverScaleListeners;
  }
  // 恢复原始样式
  el.style.transform = '';
  el.style.transition = '';
  el.style.transformBox = '';
  el.style.transformOrigin = '';
}

/**
 * 发光滤镜动画
 * @param el 目标 SVG 元素
 * @param options.blur 模糊半径，数值越大光晕越扩散，默认为 4px
 */
export function applyGlow(el: SVGElement, { blur = 4 } = {}) {
  removeGlow(el); // 清理旧的滤镜
  const svg = el.ownerSVGElement!;
  
  let defs = svg.querySelector('defs');
  if (!defs) {
    defs = document.createElementNS(svg.namespaceURI, 'defs');
    svg.insertBefore(defs, svg.firstChild);
  }
  const id = `glow-${Math.random().toString(36).slice(2)}`;
  const filter = document.createElementNS(svg.namespaceURI, 'filter');
  filter.setAttribute('id', id);
  filter.innerHTML = `
    <feGaussianBlur stdDeviation="${blur}" result="b"/>
    <feMerge>
      <feMergeNode in="b"/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>`;
  defs.appendChild(filter);
  el.style.filter = `url(#${id})`;
  el._glowFilterId = id; // 保存滤镜ID
}
/**
 * 移除发光滤镜动画
 * @param el 目标 SVG 元素
 */
export function removeGlow(el: SVGElement) {
  const id = (el as any)._glowFilterId;
  if (id && el.ownerSVGElement) {
    const svg = el.ownerSVGElement;
    const filter = svg.querySelector(`#${id}`);
    if (filter) {
      filter.parentNode?.removeChild(filter); // 确保移除 filter 元素
    }
    el.style.filter = '';
    delete (el as any)._glowFilterId;
  }
}

/**
 * 呼吸（缩放）循环动画
 * @param el 目标 SVG 元素
 * @param options.speed 呼吸速度：slow/normal/fast
 */
export function applyBreathAnimation(el: SVGElement, { speed = 'normal' as Speed } = {}) {
  el.style.transformBox = 'fill-box';
  el.style.transformOrigin = '50% 50%';
  const dur = { slow: '4s', normal: '2s', fast: '1s' }[speed];
  const className = `breathAnim-${speed}`;
  injectCSS(`
    @keyframes ${className} {
      0%   { transform: scale(1); transform-origin: 50% 50%; transform-box: fill-box; }
      50%  { transform: scale(1.05); transform-origin: 50% 50%; transform-box: fill-box; }
      100% { transform: scale(1); transform-origin: 50% 50%; transform-box: fill-box; }
    }
    .${className} { animation: ${className} ${dur} ease-in-out infinite; }
  `);
  el.classList.add(className);
}

/**
 * 移除呼吸动画类名
 * @param el 目标 SVG 元素
 */
export function removeBreathAnimation(el: SVGElement) {
  el.classList.forEach(className => {
    if (className.startsWith('breathAnim-')) {
      el.classList.remove(className);
    }
  });
}
/**
 * 旋转动画
 */
// svgAnimationManager.ts 中添加

type RotateOptions = {
  speed?: number; // 每帧角度增长速度，默认 0.1（可调节）
  active?: () => boolean; // 控制是否继续旋转的布尔函数
};

const rotateMap = new WeakMap<SVGElement, { rafId: number, rot: number }>();

export function applyRotate(el: SVGElement, { speed = 0.1, active = () => true }: RotateOptions = {}) {
  removeRotate(el); // 避免重复绑定

  let last = performance.now();
  let rot = 0;

  const step = (t: number) => {
    const dt = t - last;
    last = t;
    if (active()) {
      rot = (rot + dt * speed) % 360;
      el.style.transform = `rotate(${rot}deg)`;
      const rafId = requestAnimationFrame(step);
      rotateMap.set(el, { rafId, rot });
    }
  };
  const rafId = requestAnimationFrame(step);
  rotateMap.set(el, { rafId, rot });
}

export function removeRotate(el: SVGElement) {
  const data = rotateMap.get(el);
  if (data) {
    cancelAnimationFrame(data.rafId);
    el.style.transform = '';
    rotateMap.delete(el);
  }
}


/**
 * 将 CSS 文本注入到页面中，仅插入一次
 */
export function injectCSS(css: string) {
  const id = 'svg-anim-styles';
  let s = document.getElementById(id) as HTMLStyleElement;
  if (!s) {
    s = document.createElement('style');
    s.id = id;
    document.head.append(s);
  }
  if (!s.textContent!.includes(css)) s.textContent += css;
}

/**
 * 一次性扫描并为带有标识的元素绑定所有动画
 * @param root 根 SVG 元素
 * @param options 配置选项
 */
export function applyAnimations(
  root: SVGElement,
  runearth: boolean,
  options: { colorTarget?: string } = {}
) {
  const isRedMode = options.colorTarget === 'red';

  // 颜色变化动画（特殊处理，支持分组）
  root.querySelectorAll<SVGElement>('[data-animate="color"]').forEach(el => {
    if (options.colorTarget === 'red') {
      applyColorChange(el, runearth ? 1 : 0, 'red', 'red');
    } else {
      applyColorChange(el, runearth ? 1 : 0, options.colorTarget || '#00FF00', 'normal');
    }
  });

  // 公共动画处理函数
  const processAnimations = <T extends SVGElement>(
    selector: string,
    applyFn: (el: T) => void,
    removeFn: (el: T) => void
  ) => {
    root.querySelectorAll<T>(selector).forEach(el => {
      if (runearth) {
        removeFn(el);
        applyFn(el);
      } else {
        removeFn(el);
      }
    });
  };

  // 呼吸动画
  processAnimations('[data-animate="breath-hover"]', applyBreathAnimation, removeBreathAnimation);

  // 悬停缩放
  processAnimations('[data-animate="hover-scale"]', applyHoverScale, removeHoverScale);

  // 发光滤镜
  processAnimations('[data-animate="glow"]', applyGlow, removeGlow);

  // 闪烁动画
  processAnimations('[data-animate="blink"]', applyBlink, removeBlink);
}


  
/**
 * 添加移除动画
 */
export function clearAllAnimations(root: SVGElement) {
  // 清理所有可能的动画类型，但跳过红色锁定的元素
  root.querySelectorAll<SVGElement>('[data-animate]').forEach(el => {
    // 如果是颜色动画且有红色锁，跳过
    if (el.dataset.redLock === 'true' && el.getAttribute('data-animate') === 'color') {
      return; // 不清除红色动画
    }
    removeBreathAnimation(el);
    // removeHoverScale(el);
    removeGlow(el);
    removeColorChange(el);
    removeBlink(el);
  });

  // 清理残留滤镜（改进版）
  const svgDoc = root.ownerSVGElement || root;
  svgDoc.querySelectorAll('filter').forEach(filter => {
    if (filter.id.startsWith('glow-')) {
      filter.parentNode?.removeChild(filter);
    }
  });
}

export function clearRedLock(root: SVGElement) {
  root.querySelectorAll<SVGElement>('[data-animate="color"]').forEach(el => {
    if (el.dataset.redLock === 'true') {
      el.dataset.redLock = 'false';
      // 重新刷新颜色，优先级可能变成普通动画或恢复原色
      applyColorChange(el, 0, '', 'red');
    }
  });
}

export function clearNormalLock(root: SVGElement) {
  root.querySelectorAll<SVGElement>('[data-animate="color"]').forEach(el => {
    if (el.dataset.normalLock === 'true') {
      el.dataset.normalLock = 'false';
      applyColorChange(el, 0, '', 'normal');
    }
  });
}
/**
 * 根据布尔值批量切换 SVG 上的呼吸动画
 * @param root 根 SVG 元素
 * @param enabled 是否启用呼吸动画
 * @param speed 呼吸动画速度，默认为 normal
 */
export function toggleBreathAnimation(root: SVGElement, enabled: boolean, speed: Speed = 'normal') {
  root.querySelectorAll<SVGElement>('[data-animate="breath-hover"]').forEach(el => {
    if (enabled) {
      applyBreathAnimation(el, { speed });
    } else {
      removeBreathAnimation(el);
    }
  });
}
